import api from '@/pages/measurements/api'
import { postFile } from '@/servers/http'
import base64ToBlob from '@/utils/base64ToBlob'
import QRCode from 'qrcode.react'
import { useEffect, useImperativeHandle, useRef, useState } from 'react'

export default function (props) {
    const { data, posterRef } = props

    // 钉钉程序唤醒地址
    const dingTalkPage = 'dingtalk://dingtalkclient/action/open_mini_app?miniAppId=5000000000438545&page=pages/webViewNotPure/index.js'
    // 测评详情路由地址
    const examPage = '/measurements/'
    // 站点域名
    const [siteDomain, setSiteDomain] = useState('')
    // 测评ID
    const [evalId, setEvalId] = useState(0)

    /**
     * 根据不容内容组合适配不同的背景图
     * 关键字权重：1
     * 名称权重：10
     * （类型 | 分数）权重：100
     * 图片权重：1000
     */
    const backgrounds = {
        // 名称: 0010
        10: {
            background: 'https://static.zpimg.cn/public/career_sp/measurements/share_name.png',
            height: 624,
            width: 750,
        },
        // (类型 | 分数) + 名称: 0110
        110: {
            background: 'https://static.zpimg.cn/public/career_sp/measurements/share_type_name.png',
            height: 668,
            width: 750,
        },
        // (类型 | 分数) + 名称 + 关键字: 0111
        111: {
            background: 'https://static.zpimg.cn/public/career_sp/measurements/share_type_name_key.png',
            height: 724,
            width: 750,
        },
        // 图片 + 名称: 1010
        1010: {
            background: 'https://static.zpimg.cn/public/career_sp/measurements/share_pic_name.png',
            height: 776,
            width: 750,
        },
        // 图片 + 名称 + 关键字: 1011
        1011: {
            background: 'https://static.zpimg.cn/public/career_sp/measurements/share_pic_type_name_key.png',
            height: 876,
            width: 750,
        },
        // 图片 + 分数 + 名称
        1110: {
            background: 'https://static.zpimg.cn/public/career_sp/measurements/share_pic_point_keyword.png',
            height: 876,
            width: 750,
        },
        // 图片 + (类型 | 分数) + 名称 + 关键字: 1111
        1111: {
            background: 'https://static.zpimg.cn/public/career_sp/measurements/share_pic_type_name_key.png',
            height: 876,
            width: 750,
        },
    }

    const canvasRef = useRef()
    // 画布属性
    const [option, setOption] = useState(backgrounds.bg_name)

    useEffect(() => {
        // 获取站点地址
        let { wap_domain } = JSON.parse(localStorage.getItem('career_fe_site') || '{}')
        setSiteDomain(wap_domain)
    }, [])

    useEffect(() => {
        // 根据不同结果，选择不同背景图
        let _cover = data?.cover ? 1000 : 0
        let _type = data?.type || data?.score ? 100 : 0
        let _name = data?.name ? 10 : 0
        let _keyword = data?.keyword ? 1 : 0
        const optionKey = _cover + _type + _name + _keyword
        console.log('option ===> ', optionKey)
        let tmpOption = optionKey > 0 ? backgrounds[optionKey.toString()] : backgrounds['10']
        setOption(tmpOption)
        if (data?.id) {
            setEvalId(data.id)
            // startDraw(tmpOption, data)
        }
    }, [data])

    // const startDraw = async (option, data) => {
    //   const shareImgUrl = await onDraw(option, data)
    //   console.log(shareImgUrl)
    //   postMsgToDing('onShareApp', {
    //     type: 'internal',
    //     url: `${window.location.origin}/measurements/${data?.id}?share=1`,
    //     title: data?.examName,
    //     desc: `这个测评真的超准！【${data?.examName}】，你也来试试!`,
    //     // imageUrl: shareImgUrl,
    //   })
    // }

    // https://zh-hans.reactjs.org/docs/hooks-reference.html#useimperativehandle
    // 暴露给ref的方法,给父组件调用
    useImperativeHandle(posterRef, () => {
        return {
            onDraw: onDraw,
        }
    })

    // 上传文件返回URL
    const uploadFile = async file => {
        const res = (await postFile(api.uploads, { type: 'img', file: file })) || {}
        const { status, data } = res
        if (status !== 200) return
        const { url } = data || {}
        return url
    }

    // 生成分享图
    const onDraw = (option, result) => {
        return new Promise((resolve, reject) => {
            const ctx = canvasRef.current.getContext('2d')
            let backgroundImg = new Image()
            // IOS 下 crossOrigin 需要配置在 src 参数前
            backgroundImg.setAttribute('crossOrigin', 'Anonymous')
            backgroundImg.src = option.background
            backgroundImg.onload = async () => {
                // 背景图
                ctx.drawImage(backgroundImg, 0, 0, option.width, option.height)

                // 用户头像 40x40 左24px 上24px
                result.avatar && (await drawCircleImg(ctx, result.avatar, 48, 48, 40))

                // 用户姓名
                ctx.font = `28px PingFangSC-Regular, PingFang SC`
                // 测量绘制文本的信息
                let metrics = getTextMeasure(ctx, result.userName)
                let textHeight = metrics.height
                ctx.fillStyle = '#fff'
                ctx.fillText(result.userName || '预览', 144, 66 + textHeight)

                // 测评名称：距离顶部 88px 居中
                ctx.font = `34px PingFangSC-Regular, PingFang SC`
                let examNameText = drawCenterText(ctx, option, result.examName, 176)

                // 测评名称两边的菱形点
                ctx.font = `12px PingFangSC-Regular, PingFang SC`
                // 左侧
                ctx.fillText('◆', examNameText.startX - 20, 170 + examNameText.height / 2)
                // 右侧
                ctx.fillText('◆', examNameText.startX + examNameText.width + 10, 170 + examNameText.height / 2)

                // ↓----------距离盒子顶部44px 距背景离顶部170px 每个元素MarginTop 6px----------↓
                let resultMarginTop = 170 * 2
                // 图片 70 x 70
                if (Boolean(result.cover)) {
                    await drawPic(ctx, result.cover, resultMarginTop, option.width)
                    resultMarginTop += 76 * 2
                }

                ctx.font = `30px PingFangSC-Regular, PingFang SC bold`
                ctx.fillStyle = '#0089FF'
                // 类型
                if (Boolean(result.type)) {
                    textHeight = drawCenterText(ctx, option, result.type, resultMarginTop).height
                    resultMarginTop = resultMarginTop + textHeight * 2 + 6
                }
                // 总分
                if (Boolean(result.score)) {
                    textHeight = drawCenterText(ctx, option, `${result.score}分`, resultMarginTop).height
                    resultMarginTop = resultMarginTop + textHeight * 2 + 6
                }
                // 名称
                if (Boolean(result.name)) {
                    textHeight = drawCenterText(ctx, option, result.name, resultMarginTop).height
                    resultMarginTop = resultMarginTop + textHeight * 2 + 6 * 2
                }

                ctx.font = `28px PingFangSC-Regular, PingFang SC`
                ctx.fillStyle = 'rgba(23, 26, 29, 0.6)'
                // 关键字
                if (Boolean(result.keyword)) {
                    drawCenterText(ctx, option, '关键字: ' + result.keyword, resultMarginTop)
                }
                // ↑----------距离盒子顶部44px 距背景离顶部170px 每个元素MarginTop 6px----------↑

                // 绘制二维码边框
                strokeRoundRect(ctx, option.width - 96 - 48, option.height - 96 - 32, 96, 96, 5, 2, 'rgba(126, 134, 142, 0.24)')

                // 绘制二维码
                await drawQrCode(ctx, option)

                if (canvasRef.current) {
                    // 将画布导出为Image
                    const MIME_TYPE = 'image/png'
                    let imgURL = canvasRef.current.toDataURL(MIME_TYPE)
                    let imgBlob = base64ToBlob(imgURL, MIME_TYPE)
                    let imgFile = new window.File([imgBlob], 'share.png', { type: 'image/png' })
                    const shareImgUrl = await uploadFile(imgFile)

                    // 返回分享图URL
                    resolve(shareImgUrl)
                }
            }
        })
    }

    // 裁切图片成圆形
    const drawCircleImg = (ctx, imgSrc, x, y, r) => {
        return new Promise((resolve, reject) => {
            let img = new Image()
            img.setAttribute('crossOrigin', 'Anonymous')
            img.src = imgSrc
            img.onload = () => {
                ctx.save()
                var d = 2 * r
                var cx = x + r
                var cy = y + r
                ctx.arc(cx, cy, r, 0, 2 * Math.PI)
                ctx.clip()
                ctx.drawImage(img, x, y, d, d)
                ctx.restore()
                resolve()
            }
        })
    }

    /**
     * 绘制居中图片
     * @param {*} ctx Canvas上下文
     * @param {*} imgSrc 图片URL
     * @param {*} marginTop 距离顶部高度
     * @param {*} bgWidth 背景宽度，用于定位居中
     * @returns
     */
    const drawPic = (ctx, imgSrc, marginTop, bgWidth) => {
        return new Promise((resolve, reject) => {
            let img = new Image()
            img.setAttribute('crossOrigin', 'Anonymous')
            img.src = imgSrc + '?time=' + new Date().valueOf()
            img.onload = () => {
                ctx.save()
                // 将宽度拉伸至140高度下同比例大小
                let scale = img.height / 140
                let imgWidth = scale === 0 ? img.width : img.width / scale
                ctx.drawImage(img, (bgWidth - imgWidth) / 2, marginTop - 20, imgWidth, 140)
                ctx.restore()
                resolve()
            }
            img.onerror = err => {
                console.log('img onload err -> ', err)
                resolve()
            }
        })
    }

    // 绘制二维码
    const drawQrCode = (ctx, option) => {
        return new Promise((resolve, reject) => {
            let img = new Image()
            img.setAttribute('crossOrigin', 'Anonymous')
            img.src = document.querySelector('#qrCode')?.toDataURL('image/png')
            img.onload = () => {
                ctx.save()
                ctx.drawImage(img, option.width - 84 - 54, option.height - 84 - 36, 84, 84)
                ctx.restore()
                resolve()
            }
        })
    }

    /**
     * 绘制居中文字
     * @param {*} ctx
     * @param {*} text 要绘制的文字
     * @param {*} marginTop 距离顶部高度，用于定位
     * @returns 返回文字高度，用于下次定位
     */
    const drawCenterText = (ctx, option, text, marginTop) => {
        let metrics = getTextMeasure(ctx, text)
        let textWidth = metrics.width
        let textHeight = metrics.height
        let textStartX = (option.width - textWidth) / 2
        ctx.fillText(
            text,
            // 文字居中
            textStartX,
            marginTop + textHeight / 2,
        )
        return {
            width: textWidth,
            height: textHeight,
            startX: textStartX,
        }
    }

    // 获取Canvas绘制文字的宽高
    const getTextMeasure = (ctx, text) => {
        let metrics = ctx.measureText(text)
        // 钉钉环境下无法获取高度，这里取默认高度
        let px = ctx.font.match(/\d+px/)
        // let defaultHeight = Number(px[0]?.replace('px', '') || 24)
        return {
            width: metrics.width,
            height: metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent,
        }
    }

    /**该方法用来绘制圆角矩形
     *@param cxt:canvas的上下文环境
     *@param x:左上角x轴坐标
     *@param y:左上角y轴坐标
     *@param width:矩形的宽度
     *@param height:矩形的高度
     *@param radius:圆的半径
     *@param lineWidth:线条粗细
     *@param strokeColor:线条颜色
     **/
    function strokeRoundRect(cxt, x, y, width, height, radius, lineWidth, strokeColor) {
        //圆的直径必然要小于矩形的宽高
        if (2 * radius > width || 2 * radius > height) {
            return false
        }

        cxt.save()
        cxt.translate(x, y)
        //绘制圆角矩形的各个边
        drawRoundRectPath(cxt, width, height, radius)
        cxt.lineWidth = lineWidth || 2 //若是给定了值就用给定的值否则给予默认值2
        cxt.strokeStyle = strokeColor || '#000'
        cxt.stroke()
        cxt.restore()
    }

    function drawRoundRectPath(cxt, width, height, radius) {
        cxt.beginPath(0)
        //从右下角顺时针绘制，弧度从0到1/2PI
        cxt.arc(width - radius, height - radius, radius, 0, Math.PI / 2)

        //矩形下边线
        cxt.lineTo(radius, height)

        //左下角圆弧，弧度从1/2PI到PI
        cxt.arc(radius, height - radius, radius, Math.PI / 2, Math.PI)

        //矩形左边线
        cxt.lineTo(0, radius)

        //左上角圆弧，弧度从PI到3/2PI
        cxt.arc(radius, radius, radius, Math.PI, (Math.PI * 3) / 2)

        //上边线
        cxt.lineTo(width - radius, 0)

        //右上角圆弧
        cxt.arc(width - radius, radius, radius, (Math.PI * 3) / 2, Math.PI * 2)

        //右边线
        cxt.lineTo(width, height - radius)
        cxt.closePath()
    }

    return (
        <div>
            <QRCode style={{ display: 'none' }} value={`${dingTalkPage}?url=${siteDomain}${examPage}${evalId}`} size={84} id="qrCode" />

            <canvas style={{ display: 'none' }} width={option?.width} height={option?.height} ref={canvasRef} />
        </div>
    )
}
